package task.snake.view.swingimpl;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import task.snake.controller.ComponentListenerImpl;
import task.snake.model.SnakeModel;

/**
 * Class PlayPanel extends JPanel and represents play field.
 * <p>
 * The class PlayPanel provides constructor and override method
 * paintComponent(Graphics g) of superclass.
 * 
 * @author Nadezhda Makarkina
 * 
 */
@SuppressWarnings("serial")
public class PlayPanel extends JPanel {
	private static final int CELL_SIZE = 24;
	private static final int CELL_PADDING = 2;
	private static final Color SNAKE_COLOR = Color.YELLOW;
	private static final Color GREEN_FROGS_COLOR = Color.GREEN;
	private static final Color RED_FROGS_COLOR = Color.RED;
	private final int m; 					// width of box
	private final int n; 					// height of box
	private SnakeModel snakeModel;
	private BufferedImage buffer;	

	/**
	 * Initializes a newly created PlayPanel.
	 * 
	 * @param m
	 *            number of columns in play grid
	 * @param n
	 *            number of lines in play grid
	 */
	public PlayPanel(int m, int n) {
		setOpaque(false);
		this.m = m;
		this.n = n;
		addComponentListener(new ComponentListenerImpl(this));
	}

	/**
	 * Method override paintComponent(Graphics g) method of superclass.
	 */
	@Override
	public void paintComponent(Graphics g) {		
		if (buffer == null) {
	        rebuildBuffer();
	    }
	    g.drawImage(buffer, 0, 0, this);
	}

	/**
	 * Method paint on a buffer instead play panel
	 */
	public void rebuildBuffer(){
		int w = getWidth();
	    int h = getHeight();
		buffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
		Graphics g2 = buffer.createGraphics();
		drawGrid(g2);
		drawCreatures(g2);
	}

	/**
	 * Sets snakeModel for this panel.
	 * 
	 * @param sm
	 */
	public void setSnakeModel(SnakeModel sm) {
		this.snakeModel = sm;
	}

	/**
	 * Returns CELL_SIZE of this panel.
	 * 
	 * @return
	 */
	public static int getCellSize() {
		return CELL_SIZE;
	}

	/**
	 * Returns CELL_PADDING of this panel.
	 * 
	 * @return
	 */
	public static int getCellPadding() {
		return CELL_PADDING;
	}

	private void drawGrid(Graphics g) {
		g.setColor(Color.BLACK);
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				int x = (i + 1) * CELL_PADDING + i * CELL_SIZE;
				int y = (j + 1) * CELL_PADDING + j * CELL_SIZE;
				g.fillRect(x, y, CELL_SIZE, CELL_SIZE);
			}
		}
	}

	private void drawCreatures(Graphics g) {
		if (snakeModel == null) {
			return;
		}
		g.setColor(SNAKE_COLOR);
		// head
		// coordinate on play field
		int cellX;
		int cellY;
		// coordinates on play panel
		int x;
		int y;
		cellX = snakeModel.getSnake().getHeadLocation().x;
		cellY = snakeModel.getSnake().getHeadLocation().y;
		x = (cellX + 1) * CELL_PADDING + cellX * CELL_SIZE;
		y = (cellY + 1) * CELL_PADDING + cellY * CELL_SIZE;
		g.fillArc(x, y, CELL_SIZE, CELL_SIZE, 0, 360);
		// body
		if (snakeModel.getSnake().getLocation().size() > 2) {
			for (int i = 1; i < snakeModel.getSnake().getLocation().size() - 1; i++) {
				cellX = snakeModel.getSnake().getLocation().get(i).x;
				cellY = snakeModel.getSnake().getLocation().get(i).y;
				x = (int) ((cellX + 1) * CELL_PADDING + cellX * CELL_SIZE + CELL_SIZE / 6);
				y = (int) ((cellY + 1) * CELL_PADDING + cellY * CELL_SIZE + CELL_SIZE / 6);
				g.fillArc(x, y, (int) (CELL_SIZE / 3 * 2),
						(int) (CELL_SIZE / 3 * 2), 0, 360);
			}
		}
		// tail
		cellX = snakeModel.getSnake().getLocation().getLast().x;
		cellY = snakeModel.getSnake().getLocation().getLast().y;
		x = (int) ((cellX + 1) * CELL_PADDING + cellX * CELL_SIZE + CELL_SIZE / 4);
		y = (int) ((cellY + 1) * CELL_PADDING + cellY * CELL_SIZE + CELL_SIZE / 4);
		g.fillArc(x, y, (int) (CELL_SIZE / 2), (int) (CELL_SIZE / 2), 0, 360);
		// frogs
		for (int i = 0; i < snakeModel.getFrogs().size(); i++) {
			cellX = snakeModel.getFrogs().get(i).getHeadLocation().x;
			cellY = snakeModel.getFrogs().get(i).getHeadLocation().y;
			String frogType = snakeModel.getFrogs().get(i).getTypeOfFrog();
			if (frogType.equals("Green")){
				g.setColor(GREEN_FROGS_COLOR);
			}else if(frogType.equals("Red")){
				g.setColor(RED_FROGS_COLOR);
			}
			x = (int) ((cellX + 1) * CELL_PADDING + cellX * CELL_SIZE + CELL_SIZE / 6);
			y = (int) ((cellY + 1) * CELL_PADDING + cellY * CELL_SIZE + CELL_SIZE / 6);
			g.fillArc(x, y, (int) (CELL_SIZE / 3 * 2),
					(int) (CELL_SIZE / 3 * 2), 0, 360);
		}
	}
}


